#include "mysql.hpp"
#include "user.hxx"
#include "user-odb.hxx"

namespace xchat
{
class UserTable
{
public:
    using ptr = std::shared_ptr<UserTable>;
    UserTable(const std::shared_ptr<odb::core::database>& db) 
        : _db(db) {}
    bool insert(const std::shared_ptr<User>& user)
    {
        try
        {
            //开启事务
            //LOG_DEBUG("开启insert事务");
            odb::transaction trans(_db->begin());
            _db->persist(*user);
            //LOG_DEBUG("插入完毕");
            //提交事务
            trans.commit();
            //LOG_DEBUG("完成insert事务");
        }catch(std::exception &e){
            LOG_ERROR("新增用户失败 {} {}", !user->nickname().null() ? *user->nickname() : "", e.what());
            return false;
        }
        return true;
    }
    bool update(const std::shared_ptr<User>& user)
    {
        try
        {
            //开启事务
            odb::transaction trans(_db->begin());
            _db->update(*user);
            //提交事务
            trans.commit();
        }catch(std::exception &e){
            LOG_ERROR("更新用户失败 {} {}", !user->nickname().null() ? user->nickname().get() : "", e.what());
            return false;
        }
        return true;
    }
    std::shared_ptr<User> select_by_nickname(const std::string& nickname)
    {
        std::shared_ptr<User> res;
        try
        {
            //开启事务
            //LOG_DEBUG("开启select_by_nickname事务");
            odb::transaction trans(_db->begin());
            typedef odb::query<User> query;
            typedef odb::result<User> result;
            //_db->query_one<User> 返回user*
            res = std::shared_ptr<User>(_db->query_one<User>(query::nickname == nickname)); //调用的nickname函数 不是看的成员 
            //LOG_DEBUG("查询完毕");
            //提交事务
            trans.commit();
            //LOG_DEBUG("提交完毕");

        }catch(std::exception &e){
            LOG_ERROR("通过昵称查询用户失败 {}:{}",  nickname, e.what());
        }

        return res;
    }
    std::shared_ptr<User> select_by_phone(const std::string& phone)
    {
        std::shared_ptr<User> res;
        try
        {
            //开启事务
            odb::transaction trans(_db->begin());
            typedef odb::query<User> query;
            typedef odb::result<User> result;
            //_db->query_one<User> 返回user*
            res = std::shared_ptr<User>(_db->query_one<User>(query::phone == phone)); //调用的nickname函数 不是看的成员 
            //提交事务
            trans.commit();

        }catch(std::exception &e){
            LOG_ERROR("通过手机查询用户失败 {} {}", phone, e.what());
        }
        return res;
    }
    std::shared_ptr<User> select_by_id(const std::string& user_id)
    {
        std::shared_ptr<User> res;
        try
        {
            //开启事务
            odb::transaction trans(_db->begin());
            typedef odb::query<User> query;
            typedef odb::result<User> result;
            //_db->query_one<User> 返回user*
            res = std::shared_ptr<User>(_db->query_one<User>(query::user_id == user_id)); //调用的nickname函数 不是看的成员 
            //提交事务
            trans.commit();

        }catch(std::exception &e){
            LOG_ERROR("通过id查询用户失败 {} {}", user_id, e.what());
        }
        return res;
    }
    std::vector<User> select_multi_users(const std::vector<std::string>& id_list)
    {
        //select * from user where user_id in (id1, id2, id3)
        if(id_list.empty())
        {
            LOG_DEBUG("id列表为空 select_multi_users正常退出");
            return std::vector<User>();
        }
        std::vector<User> res;
        try
        {
            //开启事务
            odb::transaction trans(_db->begin());
            typedef odb::query<User> query;
            typedef odb::result<User> result;
            std::stringstream condition;
            condition << "user_id in (";

            // 用迭代器遍历Members，通过标记控制逗号（避免末尾多余逗号）
            bool is_first = true;
            for (const auto& id : id_list) {  // 范围for循环遍历迭代器
                LOG_DEBUG("user_id:{}", id);
                if (!is_first) {
                    condition << ",";  // 非第一个元素前加逗号
                }
                condition << "'" << id << "'";  // 拼接带单引号的id
                is_first = false;
            }
            condition << ")";  // 闭合括号

            
            //_db->query_one<User> 返回user*
            result r(_db->query<User>(condition.str()));
            for (const auto &it : r)
            {
                res.push_back(it);
            }
            //提交事务
            trans.commit();

        }catch(std::exception &e){
            LOG_ERROR("通过id列表查询用户失败 {}", e.what());
        }
        return res;
    }
private:
    std::shared_ptr<odb::core::database> _db;
};


}